package com.learning.concurrent.basic;

import lombok.extern.slf4j.Slf4j;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * description:模拟队列
 * 步骤：
 * 	<ul>
 * 	    <ol>存放元素的集合list</ol>
 * 	    <ol>计数器count（类型AtomicInteger）</ol>
 * 	    <ol>队列的上下限值</ol>
 * 	    <ol>初始化对象，用于加锁</ol>
 * 	</ul>
 * @author minghuiZhang
 * @date created in  10:53 2018/5/10
 * modified by
 */
@Slf4j
public class MyQueue<T> {
	private final LinkedList<T> list = new LinkedList<>();
	private AtomicInteger count = new AtomicInteger(0);
	private final int maxSize;
	private final int minSize = 0;

	public MyQueue(int maxSize) {
		this.maxSize = maxSize;
	}
	private final Object lock = new Object();
	public void put(T t){
		synchronized (lock){
			while (this.count.get() == this.maxSize ){
				try {
					lock.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			list.add(t);
			count.incrementAndGet();
			log.info("新加入元素为：{}",t.toString());
			lock.notify();
		}
	}

	public T take(){
		T t;
		synchronized (lock){
			while(this.count.get() == this.minSize){
				try {
					lock.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}

			 t = list.removeFirst();
			log.info("移除元素e:{}",t.toString());
			 this.count.decrementAndGet();
			 lock.notify();
		}
		return t;
	}
	public int size(){
		return this.list.size();
	}
	public static void main(String[] args) {
		final MyQueue<String> myQueue = new MyQueue<String>(5);

		myQueue.put("a");
		myQueue.put("b");
		myQueue.put("c");
		myQueue.put("d");
		myQueue.put("e");
		log.info("当前容器的长度:{}",myQueue.size());
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				myQueue.put("f");
			}
		}, "t1");
		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				myQueue.take();
			}
		}, "t2");

		t1.start();
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		t2.start();


	}
}
